package lelouet.datacenter.energy;

import gridlib.AllFactories;
import gridlib.api.Grid;
import gridlib.api.GridFactory;
import gridlib.api.Machine;
import gridlib.authentification.AuthentificationException;
import gridlib.authentification.BasicAuthentificationManager;
import gridlib.authentification.Session;
import gridlib.parser.ConfigurationParserException;
import gridlib.parser.GridConfigurationParser;

import java.io.File;
import java.rmi.RemoteException;

import lelouet.datamap.DataMap;
import lelouet.datamap.DataMapFactory;
import lelouet.datamap.Utils;

/**
 * generates a {@link DataMap} of energy consumption, from a {@link Grid}<br />
 * A specified number of server is set a specified consumption : every server
 * chosen is given that same consumption value.
 */
public class SameConsumptionGenerator {

	protected double serverConso;

	protected int aimedVMs;

	/**
	 * @param nbVMs
	 *            the number of working servers
	 * @param serverConso
	 *            the consumption of working servers
	 */
	public SameConsumptionGenerator(int nbVMs, double serverConso) {
		this.serverConso = serverConso;
		aimedVMs = nbVMs;
	}

	/** allocates to randomly chosen servers the given consumption. */
	public DataMap generate(Grid grid) {
		DataMapFactory factory = new DataMapFactory();
		DataMap ret = factory.createDataMap();
		java.util.Random ran = new java.util.Random();
		try {
			int remainingVMs = aimedVMs;
			int remainingMachines = grid.getAllMachines().size();
			for (Machine machine : grid.getAllMachines()) {
				if (ran.nextDouble() * remainingMachines < remainingVMs) {
					ret.getServerPoints().add(
							factory.createServerPoint(machine.getName(),
									serverConso));
					remainingVMs--;
				}
				remainingMachines--;
			}
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		return ret;
	}

	/**
	 * load a grid from an input file, generates its consumption model, and save
	 * it in an output file
	 * 
	 * @param in
	 *            the file to load the {@link Grid} from
	 * @param out
	 *            the file to save the {@link DataMap} to
	 */
	public void apply(File in, File out) {
		try {
			Grid parsedGrid;
			GridFactory gridFactory = AllFactories.getGridFactory();
			final GridConfigurationParser parser = new GridConfigurationParser(
					gridFactory);
			Session session = AllFactories.getAuthentificationManager().login(
					BasicAuthentificationManager.ADMIN_NAME,
					BasicAuthentificationManager.ADMIN_PASSWD);
			parsedGrid = parser.parse(session, in.getAbsolutePath());
			Utils.saveDataMap(generate(parsedGrid), out);
		} catch (RemoteException e) {
			e.printStackTrace();
		} catch (ConfigurationParserException e) {
			e.printStackTrace();
		} catch (AuthentificationException e) {
			e.printStackTrace();
		}
	}

}
